﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System.ComponentModel;
using System.Drawing;
using System.Windows.Threading;
using System.Windows.Media;
using BrainTechLLC;
using BrainTechLLC.WPF;
using BrainTechLLC.ImageOperators;
using System.Windows;
using System;
using System.Threading;
using System.Windows.Media.Imaging;
using System.Diagnostics;

namespace ImageAppDataModels
{
    public partial class FileImage : BaseNotifyPropertyChangedUI, IHasImageSource, INotifyPropertyChanged, IObjectLock, IFileImage
    {
        public bool _lazyLoadingImageSource;
        public ImageSource _imageSource;
        public double _imageSourceWidth;
        public double _imageSourceHeight;        

        public double ImageSourceWidth
        {
            get { return _imageSourceWidth; }
            set
            {
                if (_imageSourceWidth != value)
                {
                    _imageSourceWidth = value;
                    OnPropertyChanged("ImageSourceWidth");
                }
            }
        }

        public double ImageSourceHeight
        {
            get { return _imageSourceHeight; }
            set
            {
                if (_imageSourceHeight != value)
                {
                    _imageSourceHeight = value;
                    OnPropertyChanged("ImageSourceHeight");
                }
            }
        }
        
        public ImageSource GetImageSource(int width, int height, Action<FileImage> callback)
        {
            ImageSource src = ImageSourceCached;

            if (src != null && Util2.WithinWidthHeightTolerance(width, height, _imageSourceWidth, _imageSourceHeight))
            {
                return src;
            }

            if (NeedsImageSourceRefresh(width, height))
            {                
                _imageSourceWidth = width;
                _imageSourceHeight = height;

                if (LazyLoadingImageSource._lazyLoaderImageSource.Count > 4)
                {
                    LazyLoadingImageSource._lazyLoaderImageSource.CancelAll();
                }

                if (LazyLoadingImageSource._lazyLoaderImageSource.LazyLoad(this, callback))
                {
                    _lazyLoadingImageSource = true;
                }
            }

            return src;
        }

        protected bool NeedsImageSourceRefresh(int width, int height)
        {            
            return !_lazyLoadingImageSource && (_imageSource == null || !Util2.WithinWidthHeightTolerance(width, height, _imageSourceWidth, _imageSourceHeight));
        }

        public ImageSource ImageSource
        {
            get
            {
                ImageSource src = ImageSourceCached;
                
                if (src != null)
                    return src;
                    
                Bitmap bm = _bitmap;

                if (bm == null)
                {
                    src = null; // herehere
                    return null;
                }

                int width;
                int height;

                if (_imageSourceWidth > 0 && _imageSourceHeight > 0)
                {
                    width = (int)_imageSourceWidth;
                    height = (int)_imageSourceHeight;
                }
                else
                {
                    width = _originalBitmapWidth;
                    height = _originalBitmapHeight;
                }

                GetImageSource(width, height, (fi) => { fi._lazyLoadingImageSource = false; });

                return _imageSource;
            }
            set
            {
                if (_imageSource != value)
                {
                    if (_imageSource != null)
                    {                        
                        _imageSource = null;
                    }
                    _imageSource = value;

                    if (_imageSource != null)
                    {
                        RecentlyUsedFileImages.RecentlyUsedImageSources.MarkItemRecentlyUsed(this);
                    }

                    OnPropertyChanged("ImageSource");                    
                }
            }
        }

        public ImageSource ImageSourceCached
        {
            get
            {
                if (_deleted) 
                {                    
                    // Look here... maybe we shouldn't set to null?  or is this good for memory
                    if (_imageSource != null)
                    {                        
                        ImageSource = null;
                    }
                    return null;
                }

                return _imageSource;
            }
        }

        public void MarkImageSourceDirty()
        {            
            ImageSource = null;            
        }
    }
}
